home *** CD-ROM | disk | FTP | other *** search
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include "cgilib.h"
-
- extern char **environ;
-
- char **copyEnvironment(char **environment)
- {
- int numEnvvar = 0;
- const char *tmp;
- char **newEnv;
-
- /* Loop through the array */
-
- for( tmp = *environment; '\0' != *tmp; tmp += strlen(tmp)+1 )
- {
- /* Count the number of env var */
- numEnvvar++;
- }
-
- numEnvvar++; /* for the null */
-
- newEnv = malloc(numEnvvar * sizeof(char *));
-
- /* Depending on your machine, you might use memcopy here */
- bcopy(environment,newEnv,(sizeof(char *) * numEnvvar));
-
- return newEnv;
- }
-
- void setEnvVar(char ***environment, const char *envName, const char * newValue)
- {
- if(newValue && envName)
- {
- char *tmp;
- size_t length;
- int gotIt = 0, numEnvvar = 0;
-
- length = strlen(envName);
-
- /* Loop through the array */
-
- for( tmp = **environment; '\0' != *tmp; tmp += strlen(tmp)+1 )
- {
- /* Count the number of env var */
- numEnvvar++;
-
- /* Check if this is the right env variable */
- if ( !(strncmp( tmp, envName, length))
- &&( '=' == tmp[ length ] ))
- {
- int newSize;
-
- /* Calc the new size, include space for the '=' */
- newSize = strlen(envName) + strlen(newValue) + 2;
-
- /*free(tmp);*/
-
- tmp = malloc(sizeof(char) * newSize);
-
- strcpy(tmp,envName);
- strcat(tmp,"=");
- strcat(tmp,newValue);
- (*environment)[numEnvvar-1] = tmp;
- gotIt = 1;
- break;
- }
- }
-
- numEnvvar++; /* for the null */
-
- if(!gotIt)
- {
- int newSize;
-
- /* Calc the new size, include space for the '=' */
- newSize = strlen(envName) + strlen(newValue) + 2;
-
- tmp = malloc(sizeof(char) * newSize);
-
- strcpy(tmp,envName);
- strcat(tmp,"=");
- strcat(tmp,newValue);
-
- /* Grow the array by 1*/
- *environment = realloc(*environment,sizeof(char *)*(numEnvvar+1));
- (*environment)[numEnvvar-1] = tmp;
- (*environment)[numEnvvar] = (char *) 0;
- }
- }
- }
-
- void main(int argc, char *argv[])
- {
- /* Variables for the data. */
-
- Dictionary dataDict;
- String data = 0;
- const char *theScript = (char *)0,*choice = (char *)0;
- int pipeTo[2];
- int pidChild = -1;
- char buffer[16];
- char **newEnviron;
- int numFds,fd;
-
- /*
- * Get the CGI data from the CGI library
- */
- dataDict = readParse();
-
- /* figure out which radio button was pressed. */
-
- choice = dict_valueForKey(dataDict,"choice");
-
- if(choice)
- {
- if(!strcmp(choice,"vars"))
- {
- theScript = "envvar";
- }
- else
- {
- theScript = "formdata";
- }
- }
- else
- {
- theScript = "formdata";
- }
-
- /* Add some new data */
- data = string_alloc(16);
- string_setStringValue(data,"Some New Data");
- dict_setValueForKey(dataDict,"NEW",string_copyValue(data));
- string_free(data);
-
- /* Create the encoded data to send to the child */
-
- data = encodeDictionary(dataDict);
-
- /* Set up the environment */
-
- /* Copy the gloval environment */
- newEnviron = copyEnvironment(environ);
-
- /* Reset the relevent env. var. for the child */
- sprintf(buffer,"POST");
- setEnvVar(&newEnviron,"REQUEST_METHOD",buffer);
-
- sprintf(buffer,"%d",string_length(data));
- setEnvVar(&newEnviron,"CONTENT_LENGTH",buffer);
-
- /********** Fork the child process ************/
-
- if(theScript)
- {
- /* Create a set of pipes, on will be used to read,the other to write */
-
- if(pipe(pipeTo) < 0)
- {
- fprintf(stderr,"Error creating pipes to subprocess.");
- exit(1);
- }
-
- fflush(stdout);/*flush all output streams */
-
- /* Call fork, use vfork if it is available */
- switch (pidChild = vfork())
- {
- case -1: /* error */
-
- fprintf(stderr,"Error starting UNIX vfork of subprocess.");
- break;
-
- case 0: /* child */
-
- /* Use the first pipe as stdin */
- dup2(pipeTo[0], 0);
-
- close(pipeTo[0]);
-
- /* Call exec */
- execle(theScript,theScript, NULL,newEnviron);
-
- /* We should never get here, because of the exec. */
- perror("vfork:forkingCGI (child)");
-
- exit(1);
-
- default: /* parent */
-
- /* Close the reading pipe, we dont need it */
- close(pipeTo[0]);
-
- /* Write the data to the child */
- if(data && data->string)
- {
- int len,remaining,wrote = 0;
-
- len = string_length(data) * sizeof(char);
- remaining = len;
-
- while(remaining && (wrote >= 0))
- {
- wrote = write(pipeTo[1], (char *)(data->string) + (len-remaining), remaining);
- remaining -= wrote;
- }
-
- }
-
- /* Wait for the child to execute */
- if((pidChild)&&(wait((union wait *)0) !=pidChild))
- {
- /* Close the remaining pipe */
- close(pipeTo[1]);
- }
- }
- }
-
- dict_free(dataDict);
- string_free(data);
-
- /* End the program */
- exit(0);
- }
-